package org.streets.workflow.engine.mem;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.streets.workflow.engine.IActivity;
import org.streets.workflow.engine.event.INodeEventListener;
import org.streets.workflow.engine.plugin.INodeNetExtension;
import org.streets.workflow.model.net.WFActivity;


/**
 * 
 */
public class Activity extends AbstractNode implements IActivity {

    public transient static final Log log = LogFactory.getLog(Activity.class);
    public transient static final String ExtensionTargetName = "org.streets.engine.Activity";
    public transient static final String ExtensionPointNodeEventListener = "NodeEventListener";

    public transient static List<String> ExtensionPointNames = new ArrayList<String>();
    
    static {
        ExtensionPointNames.add(ExtensionPointNodeEventListener);
    }
    
    private transient WFActivity activity = null;

    public Activity(WFActivity model) {
        activity = model;
        type = NodeType.Activity;
    }

    public String getNodeId() {
        return activity.getId();
    }

    @SuppressWarnings("unchecked")
    public WFActivity getNodeModel() {
        return activity;
    }
    
//    /* (non-Javadoc)
//     * @see org.fireflow.kernel.INodeInstance#fire(org.fireflow.kernel.IToken)
//     */
//    public void fire(IToken tk) throws WorkflowException {
//        log.debug("The weight of the Entering TransitionInstance is " + tk.getValue());
//        IToken token = tk;
//        token.setNodeId(this.getActivityModel().getId());
//
//        //触发TokenEntered事件
//        NodeEvent event1 = new NodeEvent(this);
//        event1.setToken(tk);
//        event1.setEventType(NodeEvent.NODEINSTANCE_TOKEN_ENTERED);//token 来了
//        fireNodeEvent(event1);
//        if (token.isAlive()) {//如果token是活动的，那么就保存token，并创建taskinstance
//            NodeEvent event = new NodeEvent(this);
//            event.setToken(token);
//            event.setEventType(NodeEvent.NODEINSTANCE_FIRED);//token 被触发,创建taskinstance，等待
//            fireNodeEvent(event);
//        } else {//如果token是dead状态，那么就直接结束当前节点。
//            this.complete(token, null);
//        }
//    }
//
//    /* (non-Javadoc)
//     * @see org.fireflow.kernel.IActivityInstance#complete(org.fireflow.kernel.IToken, org.fireflow.kernel.IActivityInstance)
//     */
//    public void complete(IToken token, IActivity targetActivityInstance) throws WorkflowException {
//        NodeEvent event2 = new NodeEvent(this);
//        event2.setToken(token);
//        event2.setEventType(NodeEvent.NODEINSTANCE_LEAVING); //token leaving
//        fireNodeEvent(event2);
//
//
//        token.setFromActivityId(this.getActivityModel().getId());
//
//        if (targetActivityInstance != null) {
//            token.setStepNumber(token.getStepNumber() + 1);
//            targetActivityInstance.fire(token);
//        } else {
//            //按照定义，activity有且只有一个输出弧，所以此处只进行一次循环。
//            for (int i = 0; leavingTransitionInstances != null && i < leavingTransitionInstances.size(); i++) {
//                ITransition transInst = leavingTransitionInstances.get(i);
//                transInst.take(token);
//            }
//        }
//
//        if (token.isAlive()) { 
//            NodeEvent event = new NodeEvent(this);
//            event.setToken(token);
//            event.setEventType(NodeEvent.NODEINSTANCE_COMPLETED); //token completed
//            fireNodeEvent(event);
//        }
//    }

    public String getExtensionTargetName() {
        return ExtensionTargetName;
    }

    public List<String> getExtensionPointNames() {
        return ExtensionPointNames;
    }

    //TODO extesion是单态还是多实例？单态应该效率高一些。
    public void register(INodeNetExtension extension) throws RuntimeException {
        if (!ExtensionTargetName.equals(extension.getExtentionTargetName())) {
            throw new RuntimeException("Error:When construct the ActivityInstance,the Extension_Target_Name is mismatching");
        }
        if (ExtensionPointNodeEventListener.equals(extension.getExtentionPointName())) {
            if (extension instanceof INodeEventListener) {
                this.eventListeners.add((INodeEventListener) extension);
            } else {
                throw new RuntimeException("Error:When construct the ActivityInstance,the extension MUST be a instance of INodeInstanceEventListener");
            }
        }
    }

    public String toString() {
        return "ActivityInstance_4_[" + activity.getName() + "]";
    }
}
